package com.example.docking.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.example.docking.dao.jindie.GenericDataItem;
import com.example.docking.dao.jindie.ResponseData;
import com.example.docking.dao.jindie.response.*;
import com.example.docking.dao.xky.OperatePrepayParam;
import com.example.docking.dao.xky.SavePrePaymentLine;
import com.example.docking.dao.xky.SavePrePaymentOrder;
import com.example.docking.dao.xky.SavePrePaymentParam;
import com.example.docking.httpXKY.dao.BaseXKYObjResponse;
import com.example.docking.httpXKY.httpSend.XKYClient;
import com.example.docking.service.impl.DataServiceImpl;
import com.example.docking.util.Constants;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.smecloud.apigw.model.ApiResult;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import static com.example.docking.httpXKY.httpSend.XKYClient.ERP_CODE;

@Slf4j
@Controller
public class ERPApPreCreditController {
    public void selectApPreCredit() {
        // 1.查询预付款单列表
        List<ApPreCreditItem> apPreCreditList = selectApPreCreditList();
        for (ApPreCreditItem apPreCreditItem : apPreCreditList) {
            // 2.查询预付款单详情
            ApPreCreditDetail apPreCreditDetail = selectApPreCreditDetail(apPreCreditItem.getId());
            log.info("预收单详情：{}", JSON.toJSONString(apPreCreditDetail));
            if (StringUtils.isNotBlank(apPreCreditDetail.getRemark()) && apPreCreditDetail.getRemark().startsWith("携客云同步，勿动")) {
                log.info("付款单已同步成功，跳过");
                continue;
            }
            // 3.预收单推送XKY
            String xkyNo = saveApPreCredit(apPreCreditDetail);
            if (StringUtils.isBlank(xkyNo)) {
                log.info("付款单推送XKY失败");
                continue;
            }
            log.info("xkyNo:{}", xkyNo);
            // 4.XKY预付款单审批
            //updateApPreCreditStatus(xkyNo);
            // 5.回写预售单号到金蝶
            updateApPreCreditNo(apPreCreditDetail, xkyNo);
        }
    }

    /**
     * 查询预付款单列表
     *
     * @return
     */
    @SneakyThrows
    private List<ApPreCreditItem> selectApPreCreditList() {
        List<ApPreCreditItem> result = new ArrayList<>();
        DataServiceImpl service = new DataServiceImpl();
        Gson gson = new Gson();
        int page = 1;
        HashMap<String, String> map = new HashMap<>();
        long currentTimeMillis = System.currentTimeMillis();
        map.put("bill_status", "C");
        map.put("create_end_time", String.valueOf(currentTimeMillis));
        map.put("create_start_time", String.valueOf(currentTimeMillis - 60 * 60 * 1000));
        map.put("page_size", String.valueOf(100));
        List<ApPreCreditItem> creditData;
        do {
            map.put("page", String.valueOf(page++));
            ApiResult detailCredit = service.SelectDataList(Constants.PRE_CREDIT, map, "");
            Type MateriaDataType = new TypeToken<ResponseData<GenericDataItem<ApPreCreditItem>>>() {
            }.getType();
            ResponseData<GenericDataItem<ApPreCreditItem>> detailCreditData = gson.fromJson(detailCredit.getBody(), MateriaDataType);
            GenericDataItem<ApPreCreditItem> genericDataItemCredit = detailCreditData.getData();
            creditData = genericDataItemCredit.getRows();
            result.addAll(creditData);
        } while (creditData.size() >= 100);
        return result;
    }

    /**
     * 查询预付款单详情
     *
     * @param id
     * @return
     */
    @SneakyThrows
    private ApPreCreditDetail selectApPreCreditDetail(String id) {
        DataServiceImpl service = new DataServiceImpl();
        Gson gson = new Gson();
        HashMap<String, String> map = new HashMap<>();
        map.put("id", id);
        ApiResult result = service.SelectDataDetail(Constants.PRE_CREDIT_DETAIL, map, "");
        Type type2 = new TypeToken<ResponseData<ApPreCreditDetail>>() {
        }.getType();
        ResponseData<ApPreCreditDetail> response = gson.fromJson(result.getBody(), type2);
        return response.getData();
    }

    /**
     * 保存预付款单
     *
     * @param apPreCreditDetail
     */
    @SneakyThrows
    private String saveApPreCredit(ApPreCreditDetail apPreCreditDetail) {
        SavePrePaymentParam param = new SavePrePaymentParam();
        param.setErpCode(ERP_CODE);

        SavePrePaymentOrder order = new SavePrePaymentOrder();
        order.setPpmInnerXkNo(apPreCreditDetail.getBill_no());
        order.setInnerVendorCode(apPreCreditDetail.getSupplier_number());
        order.setCurrencyCode(apPreCreditDetail.getCurrency_number());
        order.setCurrencyName(apPreCreditDetail.getCurrency_name());
        order.setErpOrgCode(apPreCreditDetail.getDept_number());
        order.setErpOrgName(apPreCreditDetail.getDept_name());

        // 获取供应商信息
        SupplierData supplier = getSupplier(apPreCreditDetail.getSupplier_id());
        order.setVendorCreditCode(supplier.getTaxpayer_no());
        order.setVendorBankCode(supplier.getBank_code());
        order.setVendorBankName(supplier.getBank());
        order.setVendorBankCardNo(supplier.getBank_account());

        // 设置支付方式
        PayEntry payEntry = apPreCreditDetail.getPay_entry_list().get(0);
        order.setPaymentTypeCode(payEntry.getPay_type_number());
        order.setPaymentTypeName(payEntry.getPay_type_name());

        // 设置实际付款金额
        order.setActualReceiptTotalTaxAmount(Double.valueOf(apPreCreditDetail.getTotal_amount()));

        // 设置预付款明细
        setLineList(order, apPreCreditDetail);

        param.setOrder(order);
        param.setIsPublish(1);
        param.setIsAutoAudit(1);

        String url = "https://openapi.xiekeyun.com/prepay/insertOrUpdate.json";
        String response = XKYClient.sendRequest(url, param);
        log.info("response:{}", response);
        BaseXKYObjResponse<String> xkyObjResponse = JSONObject.parseObject(response, new TypeReference<BaseXKYObjResponse<String>>() {
        }.getType());
        log.info("xkyObjResponse:{}", xkyObjResponse);
        return xkyObjResponse.getData();
    }

    private void setLineList(SavePrePaymentOrder order, ApPreCreditDetail apPreCreditDetail) {
        List<SavePrePaymentLine> lineList = new ArrayList<>();
        List<SourceBillEntry> sourceBillEntryList = apPreCreditDetail.getSource_bill_entry_list();

        for (SourceBillEntry sourceBillEntry : sourceBillEntryList) {
            SavePrePaymentLine line = new SavePrePaymentLine();
            // 预付款单通常关联采购订单
            line.setPoErpNo(sourceBillEntry.getSrc_bill_no());
            line.setPrepayAmount(Double.valueOf(sourceBillEntry.getCur_settle_amount()));
            line.setCurDesc("单据日期：" + apPreCreditDetail.getBill_date());
            lineList.add(line);
        }

        order.setLineList(lineList);
    }

    private SupplierData getSupplier(String id) throws Exception {
        DataServiceImpl service = new DataServiceImpl();
        Gson gson = new Gson();
        HashMap<String, String> map = new HashMap<>();
        map.put("id", id);
        ApiResult DataResult = service.SelectDataDetail(Constants.SUPPLIER_DETAIL, map, "");
        Type SupplierDataType = new TypeToken<ResponseData<SupplierData>>() {
        }.getType();
        ResponseData<SupplierData> responseSupplierData = gson.fromJson(DataResult.getBody(), SupplierDataType);
        SupplierData supplierData = responseSupplierData.getData();
        List<AccountEntity> accountEntityList = supplierData.getAccount_entity();
        for (AccountEntity accountEntity : accountEntityList) {
            if (accountEntity.isAcct_is_default()) {
                supplierData.setBank_code(accountEntity.getIncome_bank_code());
                supplierData.setBank(accountEntity.getIncome_bank_name());
                supplierData.setBank_account(accountEntity.getIncome_acc_no());
            }
        }
        return supplierData;
    }

    /**
     * XKY预付款单审批（审核）
     *
     * @param xkyNo 携客云平台单号
     */
    @SneakyThrows
    private void updateApPreCreditStatus(String xkyNo) {
        OperatePrepayParam param = new OperatePrepayParam(XKYClient.ERP_CODE, xkyNo, 2, "自动审核");
        String url = "https://openapi.xiekeyun.com/prepay/operate.json";
        String result = XKYClient.sendRequest(url, param);
        log.info("XKY预付款单审批返回: {}", result);
    }

    /**
     * 回写预售单号到金蝶
     *
     * @param apPreCreditDetail
     * @param xkyNo
     */
    @SneakyThrows
    private void updateApPreCreditNo(ApPreCreditDetail apPreCreditDetail, String xkyNo) {
        String remark = apPreCreditDetail.getRemark();
        remark = "携客云同步，勿动" + xkyNo + " " + remark;
        apPreCreditDetail.setRemark(remark);
        DataServiceImpl service = new DataServiceImpl();
        HashMap<String, String> map = new HashMap<>();
        service.UpdateData(Constants.PRE_CREDIT, map, apPreCreditDetail);
    }

    public static void main(String[] args) {
        ERPApPreCreditController erpApPreCreditController = new ERPApPreCreditController();
        erpApPreCreditController.selectApPreCredit();
    }
}
